In [3]:
# For Windows (precompiled wheels are available via unofficial sources):
!pip install TA-Lib

# For macOS/Linux you may need to install the C library first:
# macOS:
!brew install ta-lib

# Ubuntu/Debian:
!sudo apt-get install -y libta-lib0 libta-lib-dev

# Then:
!pip install TA-Lib
Requirement already satisfied: TA-Lib in e:\installedsoftware\anaconda_2\lib\site-packages (0.6.3)
Requirement already satisfied: setuptools in e:\installedsoftware\anaconda_2\lib\site-packages (from TA-Lib) (68.0.0)
Requirement already satisfied: numpy in e:\installedsoftware\anaconda_2\lib\site-packages (from TA-Lib) (1.26.4)
'brew' is not recognized as an internal or external command,
operable program or batch file.
'sudo' is not recognized as an internal or external command,
operable program or batch file.
Requirement already satisfied: TA-Lib in e:\installedsoftware\anaconda_2\lib\site-packages (0.6.3)
Requirement already satisfied: setuptools in e:\installedsoftware\anaconda_2\lib\site-packages (from TA-Lib) (68.0.0)
Requirement already satisfied: numpy in e:\installedsoftware\anaconda_2\lib\site-packages (from TA-Lib) (1.26.4)
In [4]:
import talib
In [6]:
!pip install --upgrade yfinance
Requirement already satisfied: yfinance in e:\installedsoftware\anaconda_2\lib\site-packages (0.2.37)
ERROR: Could not install packages due to an OSError: [Errno 28] No space left on device

Collecting yfinance
  Obtaining dependency information for yfinance from https://files.pythonhosted.org/packages/73/b5/d50eec88bc731bb8570ae42a9b764a36144e217361c33fa068391ff59ba3/yfinance-0.2.61-py2.py3-none-any.whl.metadata
  Downloading yfinance-0.2.61-py2.py3-none-any.whl.metadata (5.8 kB)
Requirement already satisfied: pandas>=1.3.0 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2.0.3)
Requirement already satisfied: numpy>=1.16.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (1.26.4)
Requirement already satisfied: requests>=2.31 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2.31.0)
Requirement already satisfied: multitasking>=0.0.7 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (0.0.11)
Requirement already satisfied: platformdirs>=2.0.0 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (3.10.0)
Requirement already satisfied: pytz>=2022.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2024.1)
Requirement already satisfied: frozendict>=2.3.4 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2.4.1)
Requirement already satisfied: peewee>=3.16.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (3.17.1)
Requirement already satisfied: beautifulsoup4>=4.11.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (4.12.2)
Collecting curl_cffi>=0.7 (from yfinance)
  Obtaining dependency information for curl_cffi>=0.7 from https://files.pythonhosted.org/packages/ea/fb/77dcb3e9fccf368dd58a1fdb8f8ace75dc6579a2701f57af625b00bc781f/curl_cffi-0.11.2-cp39-abi3-win_amd64.whl.metadata
  Downloading curl_cffi-0.11.2-cp39-abi3-win_amd64.whl.metadata (15 kB)
Requirement already satisfied: protobuf>=3.19.0 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (4.25.5)
Collecting websockets>=13.0 (from yfinance)
  Obtaining dependency information for websockets>=13.0 from https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl.metadata
  Downloading websockets-15.0.1-cp311-cp311-win_amd64.whl.metadata (7.0 kB)
Requirement already satisfied: soupsieve>1.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from beautifulsoup4>=4.11.1->yfinance) (2.4)
Requirement already satisfied: cffi>=1.12.0 in e:\installedsoftware\anaconda_2\lib\site-packages (from curl_cffi>=0.7->yfinance) (1.15.1)
Requirement already satisfied: certifi>=2024.2.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from curl_cffi>=0.7->yfinance) (2024.2.2)
Requirement already satisfied: python-dateutil>=2.8.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas>=1.3.0->yfinance) (2.8.2)
Requirement already satisfied: tzdata>=2022.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas>=1.3.0->yfinance) (2024.1)
Requirement already satisfied: charset-normalizer<4,>=2 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (2.0.4)
Requirement already satisfied: idna<4,>=2.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (1.26.16)
Requirement already satisfied: pycparser in e:\installedsoftware\anaconda_2\lib\site-packages (from cffi>=1.12.0->curl_cffi>=0.7->yfinance) (2.21)
Requirement already satisfied: six>=1.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from python-dateutil>=2.8.2->pandas>=1.3.0->yfinance) (1.16.0)
Downloading yfinance-0.2.61-py2.py3-none-any.whl (117 kB)
   ---------------------------------------- 0.0/117.9 kB ? eta -:--:--
   --- ------------------------------------ 10.2/117.9 kB ? eta -:--:--
   --------------------------- ------------ 81.9/117.9 kB 1.2 MB/s eta 0:00:01
   ---------------------------------------- 117.9/117.9 kB 1.1 MB/s eta 0:00:00
Downloading curl_cffi-0.11.2-cp39-abi3-win_amd64.whl (1.4 MB)
   ---------------------------------------- 0.0/1.4 MB ? eta -:--:--
   --- ------------------------------------ 0.1/1.4 MB 2.4 MB/s eta 0:00:01
   ------- -------------------------------- 0.3/1.4 MB 3.9 MB/s eta 0:00:01
   ------------- -------------------------- 0.5/1.4 MB 3.7 MB/s eta 0:00:01
   -------------- ------------------------- 0.5/1.4 MB 3.2 MB/s eta 0:00:01
   -------------- ------------------------- 0.5/1.4 MB 3.2 MB/s eta 0:00:01
   -------------- ------------------------- 0.5/1.4 MB 3.2 MB/s eta 0:00:01
   -------------- ------------------------- 0.5/1.4 MB 3.2 MB/s eta 0:00:01
   ------------------- -------------------- 0.7/1.4 MB 1.9 MB/s eta 0:00:01
   -------------------- ------------------- 0.7/1.4 MB 1.9 MB/s eta 0:00:01
   -------------------- ------------------- 0.7/1.4 MB 1.9 MB/s eta 0:00:01
   -------------------- ------------------- 0.7/1.4 MB 1.9 MB/s eta 0:00:01
   -------------------- ------------------- 0.7/1.4 MB 1.9 MB/s eta 0:00:01
   ------------------------ --------------- 0.9/1.4 MB 1.5 MB/s eta 0:00:01
   ------------------------ --------------- 0.9/1.4 MB 1.5 MB/s eta 0:00:01
   -------------------------------- ------- 1.2/1.4 MB 1.7 MB/s eta 0:00:01
   --------------------------------- ------ 1.2/1.4 MB 1.6 MB/s eta 0:00:01
   ----------------------------------- ---- 1.2/1.4 MB 1.6 MB/s eta 0:00:01
   ----------------------------------- ---- 1.3/1.4 MB 1.6 MB/s eta 0:00:01
   ----------------------------------- ---- 1.3/1.4 MB 1.6 MB/s eta 0:00:01
   ---------------------------------------  1.4/1.4 MB 1.5 MB/s eta 0:00:01
   ---------------------------------------- 1.4/1.4 MB 1.5 MB/s eta 0:00:00
Downloading websockets-15.0.1-cp311-cp311-win_amd64.whl (176 kB)
   ---------------------------------------- 0.0/176.8 kB ? eta -:--:--
   --------- ----------------------------- 41.0/176.8 kB 960.0 kB/s eta 0:00:01
   ------------------------- -------------- 112.6/176.8 kB 1.6 MB/s eta 0:00:01
   ---------------------------------------- 176.8/176.8 kB 1.3 MB/s eta 0:00:00
Installing collected packages: websockets, curl_cffi, yfinance
  Attempting uninstall: websockets
    Found existing installation: websockets 10.4
    Uninstalling websockets-10.4:
      Successfully uninstalled websockets-10.4
  Rolling back uninstall of websockets
  Moving to e:\installedsoftware\anaconda_2\lib\site-packages\websockets-10.4.dist-info\
   from E:\installedSoftware\anaconda_2\Lib\site-packages\~ebsockets-10.4.dist-info
  Moving to e:\installedsoftware\anaconda_2\lib\site-packages\websockets\
   from E:\installedSoftware\anaconda_2\Lib\site-packages\~ebsockets
In [15]:
import yfinance as yf

ticker = yf.Ticker("AAPL")
hist = ticker.history(period="1mo", )

print(hist.tail())
AAPL: No price data found, symbol may be delisted (period=1mo)
Empty DataFrame
Columns: [Open, High, Low, Close, Adj Close, Volume]
Index: []
In [14]:
!pip install yfinance
Requirement already satisfied: yfinance in e:\installedsoftware\anaconda_2\lib\site-packages (0.2.37)
Requirement already satisfied: pandas>=1.3.0 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2.0.3)
Requirement already satisfied: numpy>=1.16.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (1.26.4)
Requirement already satisfied: requests>=2.31 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2.31.0)
Requirement already satisfied: multitasking>=0.0.7 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (0.0.11)
Requirement already satisfied: lxml>=4.9.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (4.9.3)
Requirement already satisfied: appdirs>=1.4.4 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (1.4.4)
Requirement already satisfied: pytz>=2022.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2024.1)
Requirement already satisfied: frozendict>=2.3.4 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (2.4.1)
Requirement already satisfied: peewee>=3.16.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (3.17.1)
Requirement already satisfied: beautifulsoup4>=4.11.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (4.12.2)
Requirement already satisfied: html5lib>=1.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from yfinance) (1.1)
Requirement already satisfied: soupsieve>1.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from beautifulsoup4>=4.11.1->yfinance) (2.4)
Requirement already satisfied: six>=1.9 in e:\installedsoftware\anaconda_2\lib\site-packages (from html5lib>=1.1->yfinance) (1.16.0)
Requirement already satisfied: webencodings in e:\installedsoftware\anaconda_2\lib\site-packages (from html5lib>=1.1->yfinance) (0.5.1)
Requirement already satisfied: python-dateutil>=2.8.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas>=1.3.0->yfinance) (2.8.2)
Requirement already satisfied: tzdata>=2022.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas>=1.3.0->yfinance) (2024.1)
Requirement already satisfied: charset-normalizer<4,>=2 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (2.0.4)
Requirement already satisfied: idna<4,>=2.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (1.26.16)
Requirement already satisfied: certifi>=2017.4.17 in e:\installedsoftware\anaconda_2\lib\site-packages (from requests>=2.31->yfinance) (2024.2.2)
In [12]:
import yfinance as yf

# 1 মিনিট ইন্টারভালের জন্য (সর্বোচ্চ 7 দিন)
data_1m = yf.download('TSLA', period='7d', interval='1m')

# 15 মিনিট ইন্টারভালের জন্য (সর্বোচ্চ 60 দিন)
data_15m = yf.download('TSLA', period='60d', interval='15m')

# 1 ঘণ্টা ইন্টারভালের জন্য (সর্বোচ্চ 730 দিন)
data_1h = yf.download('TSLA', period='730d', interval='60m')

# দৈনিক ইন্টারভালের জন্য (10 বছর)
data_daily = yf.download('TSLA', period='10y', interval='1d')
[*********************100%%**********************]  1 of 1 completed

1 Failed download:
['TSLA']: JSONDecodeError('Expecting value: line 1 column 1 (char 0)')
[*********************100%%**********************]  1 of 1 completed

1 Failed download:
['TSLA']: JSONDecodeError('Expecting value: line 1 column 1 (char 0)')
[*********************100%%**********************]  1 of 1 completed

1 Failed download:
['TSLA']: JSONDecodeError('Expecting value: line 1 column 1 (char 0)')
[*********************100%%**********************]  1 of 1 completed

1 Failed download:
['TSLA']: JSONDecodeError('Expecting value: line 1 column 1 (char 0)')
In [71]:
!pip install pandas_ta
Collecting pandas_ta
  Using cached pandas_ta-0.3.14b0-py3-none-any.whl
Requirement already satisfied: pandas in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas_ta) (2.0.3)
Requirement already satisfied: python-dateutil>=2.8.2 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas->pandas_ta) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas->pandas_ta) (2024.1)
Requirement already satisfied: tzdata>=2022.1 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas->pandas_ta) (2024.1)
Requirement already satisfied: numpy>=1.21.0 in e:\installedsoftware\anaconda_2\lib\site-packages (from pandas->pandas_ta) (1.26.4)
Requirement already satisfied: six>=1.5 in e:\installedsoftware\anaconda_2\lib\site-packages (from python-dateutil>=2.8.2->pandas->pandas_ta) (1.16.0)
Installing collected packages: pandas_ta
ERROR: Could not install packages due to an OSError: [Errno 28] No space left on device

In [67]:
data = pd.read_csv("tesla_1h.csv", header=0)
data.head()
Out[67]:
Price Close High Low Open Volume
0 Ticker TSLA TSLA TSLA TSLA TSLA
1 Datetime NaN NaN NaN NaN NaN
2 2022-07-12 13:30:00+00:00 230.34849548339844 239.77333068847656 228.3683319091797 236.84666442871094 10409515
3 2022-07-12 14:30:00+00:00 235.1599884033203 235.94329833984375 228.88336181640625 230.3523712158203 5272402
4 2022-07-12 15:30:00+00:00 234.0666961669922 235.5933380126953 232.35963439941406 235.2033233642578 3263104
In [68]:
data.info
Out[68]:
<bound method DataFrame.info of                           Price               Close                High  \
0                        Ticker                TSLA                TSLA   
1                      Datetime                 NaN                 NaN   
2     2022-07-12 13:30:00+00:00  230.34849548339844  239.77333068847656   
3     2022-07-12 14:30:00+00:00   235.1599884033203  235.94329833984375   
4     2022-07-12 15:30:00+00:00   234.0666961669922   235.5933380126953   
...                         ...                 ...                 ...   
5083  2025-06-06 15:30:00+00:00   300.4549865722656               302.5   
5084  2025-06-06 16:30:00+00:00  300.06500244140625  302.04998779296875   
5085  2025-06-06 17:30:00+00:00   300.2900085449219    301.739990234375   
5086  2025-06-06 18:30:00+00:00   297.9898986816406               302.0   
5087  2025-06-06 19:30:00+00:00             295.125   298.2900085449219   

                     Low                Open    Volume  
0                   TSLA                TSLA      TSLA  
1                    NaN                 NaN       NaN  
2      228.3683319091797  236.84666442871094  10409515  
3     228.88336181640625   230.3523712158203   5272402  
4     232.35963439941406   235.2033233642578   3263104  
...                  ...                 ...       ...  
5083  299.30999755859375    301.090087890625  13827902  
5084  299.12689208984375        300.43359375   9565690  
5085   299.1700134277344   300.0643005371094   8608433  
5086  296.55999755859375  300.30999755859375  13412582  
5087   293.1400146484375  297.94000244140625  15789319  

[5088 rows x 6 columns]>
In [69]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [48]:
import yfinance as yf
import talib
import pandas as pd
import matplotlib.pyplot as plt

data = df

# Calculate indicators
data['SMA_20'] = talib.SMA(data['Close'], timeperiod=20)
data['EMA_20'] = talib.EMA(data['Close'], timeperiod=20)
data['RSI'] = talib.RSI(data['Close'], timeperiod=14)
data['MACD'], data['MACD_signal'], data['MACD_hist'] = talib.MACD(data['Close'], fastperiod=12, slowperiod=26, signalperiod=9)

# Display part of the DataFrame
print(data[['Close', 'SMA_20', 'EMA_20', 'RSI', 'MACD']].tail())

# Plot Close price and indicators
plt.figure(figsize=(12, 6))
plt.plot(data['Close'], label='Close Price')
plt.plot(data['SMA_20'], label='SMA 20')
plt.plot(data['EMA_20'], label='EMA 20')
plt.title('Tesla Price and Moving Averages')
plt.legend()
plt.show()
                                Close      SMA_20      EMA_20        RSI  \
Datetime                                                                   
2025-06-06 15:30:00+00:00  300.454987  319.331622  314.684308  35.483621   
2025-06-06 16:30:00+00:00  300.065002  316.957092  313.291993  35.281959   
2025-06-06 17:30:00+00:00  300.290009  314.541592  312.053709  35.509690   
2025-06-06 18:30:00+00:00  297.989899  312.217587  310.714298  34.185420   
2025-06-06 19:30:00+00:00  295.125000  310.363788  309.229603  32.556810   

                                MACD  
Datetime                              
2025-06-06 15:30:00+00:00 -13.527546  
2025-06-06 16:30:00+00:00 -13.001913  
2025-06-06 17:30:00+00:00 -12.423972  
2025-06-06 18:30:00+00:00 -12.013071  
2025-06-06 19:30:00+00:00 -11.782777  
In [50]:
import plotly.graph_objects as go

# Create a Plotly figure
fig = go.Figure()

# Add Close Price
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['Close'],
    mode='lines',
    name='Close Price'
))

# Add SMA 20
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['SMA_20'],
    mode='lines',
    name='SMA 20'
))

# Add EMA 20
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['EMA_20'],
    mode='lines',
    name='EMA 20'
))

# Set layout
fig.update_layout(
    title='AAPL Price and Moving Averages (Interactive)',
    xaxis_title='Date',
    yaxis_title='Price',
    template='plotly_dark',
    hovermode='x unified'
)

# Show plot
fig.show()
In [70]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go
import matplotlib.pyplot as plt

data = df

# Calculate indicators
data['SMA_20'] = talib.SMA(data['Close'], timeperiod=20)
data['EMA_20'] = talib.EMA(data['Close'], timeperiod=20)
data['RSI'] = talib.RSI(data['Close'], timeperiod=14)
data['MACD'], data['MACD_signal'], data['MACD_hist'] = talib.MACD(data['Close'], fastperiod=12, slowperiod=26, signalperiod=9)

# Display part of the DataFrame
print(data[['Close', 'SMA_20', 'EMA_20', 'RSI', 'MACD']].tail())



# Create a Plotly figure
fig = go.Figure()

# Add Close Price
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['Close'],
    mode='lines',
    name='Close Price'
))

# Add SMA 20
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['SMA_20'],
    mode='lines',
    name='SMA 20'
))

# Add EMA 20
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['EMA_20'],
    mode='lines',
    name='EMA 20'
))

# Add RSI
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['RSI'],
    mode='lines',
    name='RSI '
))

# Add MACD
fig.add_trace(go.Scatter(
    x=data.index,
    y=data['MACD'],
    mode='lines',
    name='MACD'
))

# Set layout
fig.update_layout(
    title='AAPL Price and Moving Averages (Interactive)',
    xaxis_title='Date',
    yaxis_title='Price',
    template='plotly_dark',
    hovermode='x unified'
)

# Show plot
fig.show()
                                Close      SMA_20      EMA_20        RSI  \
Datetime                                                                   
2025-06-06 15:30:00+00:00  300.454987  319.331622  314.684308  35.483621   
2025-06-06 16:30:00+00:00  300.065002  316.957092  313.291993  35.281959   
2025-06-06 17:30:00+00:00  300.290009  314.541592  312.053709  35.509690   
2025-06-06 18:30:00+00:00  297.989899  312.217587  310.714298  34.185420   
2025-06-06 19:30:00+00:00  295.125000  310.363788  309.229603  32.556810   

                                MACD  
Datetime                              
2025-06-06 15:30:00+00:00 -13.527546  
2025-06-06 16:30:00+00:00 -13.001913  
2025-06-06 17:30:00+00:00 -12.423972  
2025-06-06 18:30:00+00:00 -12.013071  
2025-06-06 19:30:00+00:00 -11.782777  
In [1]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [2]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

# Download data
data = df

# === Indicator Calculation ===
data['ADX'] = talib.ADX(data['High'], data['Low'], data['Close'], timeperiod=14)
data['CCI'] = talib.CCI(data['High'], data['Low'], data['Close'], timeperiod=20)
data['ATR'] = talib.ATR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['OBV'] = talib.OBV(data['Close'], data['Volume'])

# === Print tail for verification ===
print(data[['Close', 'ADX', 'CCI', 'ATR', 'OBV']].tail())

# === Plotly Chart ===
fig = go.Figure()

# Close price
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))

# ADX
fig.add_trace(go.Scatter(x=data.index, y=data['ADX'], mode='lines', name='ADX (Trend Strength)'))

# CCI
fig.add_trace(go.Scatter(x=data.index, y=data['CCI'], mode='lines', name='CCI (Momentum)'))

# ATR
fig.add_trace(go.Scatter(x=data.index, y=data['ATR'], mode='lines', name='ATR (Volatility)'))

# OBV
fig.add_trace(go.Scatter(x=data.index, y=data['OBV'], mode='lines', name='OBV (Volume)'))

# Layout
fig.update_layout(
    title='AAPL Indicators: ADX, CCI, ATR, OBV',
    xaxis_title='Date',
    yaxis_title='Value',
    template='plotly_dark',
    hovermode='x unified'
)

# Show
fig.show()
                                Close        ADX        CCI       ATR  \
Datetime                                                                
2025-06-06 15:30:00+00:00  300.454987  47.604899 -74.149204  8.609044   
2025-06-06 16:30:00+00:00  300.065002  47.317368 -67.978245  8.202905   
2025-06-06 17:30:00+00:00  300.290009  47.050375 -60.642917  7.800553   
2025-06-06 18:30:00+00:00  297.989899  46.978857 -59.967111  7.631942   
2025-06-06 19:30:00+00:00  295.125000  47.136630 -67.531000  7.454660   

                                    OBV  
Datetime                                 
2025-06-06 15:30:00+00:00  2.136260e+09  
2025-06-06 16:30:00+00:00  2.126695e+09  
2025-06-06 17:30:00+00:00  2.135303e+09  
2025-06-06 18:30:00+00:00  2.121891e+09  
2025-06-06 19:30:00+00:00  2.106101e+09  
In [3]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [4]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

# Download data

data = df

# === Indicator Calculation ===
data['ADX'] = talib.ADX(data['High'], data['Low'], data['Close'], timeperiod=14)
data['CCI'] = talib.CCI(data['High'], data['Low'], data['Close'], timeperiod=20)
data['ATR'] = talib.ATR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['OBV'] = talib.OBV(data['Close'], data['Volume'])

# === Buy/Sell Logic ===
data['Signal'] = 'Hold'
data['OBV_diff'] = data['OBV'].diff()

buy_signal = (data['CCI'] > 100) & (data['ADX'] > 25) & (data['OBV_diff'] > 0)
sell_signal = (data['CCI'] < -100) & (data['ADX'] > 25) & (data['OBV_diff'] < 0)

data.loc[buy_signal, 'Signal'] = 'Buy'
data.loc[sell_signal, 'Signal'] = 'Sell'

# === Backtesting (simplified) ===
position = None
entry_price = 0
returns = []

for i in range(len(data)):
    if data['Signal'].iloc[i] == 'Buy' and position != 'Buy':
        entry_price = data['Close'].iloc[i]
        position = 'Buy'
    elif data['Signal'].iloc[i] == 'Sell' and position == 'Buy':
        exit_price = data['Close'].iloc[i]
        returns.append(exit_price - entry_price)
        position = None

# === Summary ===
print(data[['Close', 'ADX', 'CCI', 'ATR', 'OBV', 'Signal']].tail())
print(f"Total Trades: {len(returns)}")
print(f"Total Profit/Loss: {sum(returns):.2f}")

# === Plotly Chart ===
fig = go.Figure()

# Close price
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))

# ADX
fig.add_trace(go.Scatter(x=data.index, y=data['ADX'], mode='lines', name='ADX'))

# CCI
fig.add_trace(go.Scatter(x=data.index, y=data['CCI'], mode='lines', name='CCI'))

# ATR
fig.add_trace(go.Scatter(x=data.index, y=data['ATR'], mode='lines', name='ATR'))

# OBV on secondary y-axis
fig.add_trace(go.Scatter(x=data.index, y=data['OBV'], mode='lines', name='OBV', yaxis="y2"))

# Buy/Sell Markers
fig.add_trace(go.Scatter(
    x=data.index[data['Signal'] == 'Buy'],
    y=data['Close'][data['Signal'] == 'Buy'],
    mode='markers',
    name='Buy',
    marker=dict(color='green', size=10, symbol='triangle-up')
))
fig.add_trace(go.Scatter(
    x=data.index[data['Signal'] == 'Sell'],
    y=data['Close'][data['Signal'] == 'Sell'],
    mode='markers',
    name='Sell',
    marker=dict(color='red', size=10, symbol='triangle-down')
))

# Layout adjustments
fig.update_layout(
    title='AAPL Indicators + Buy/Sell + Backtest',
    xaxis_title='Date',
    yaxis_title='Price / Indicator',
    yaxis2=dict(
        title='OBV',
        overlaying='y',
        side='right',
        showgrid=False
    ),
    template='plotly_dark',
    hovermode='x unified',
    height=700
)

fig.show()
                                Close        ADX        CCI       ATR  \
Datetime                                                                
2025-06-06 15:30:00+00:00  300.454987  47.604899 -74.149204  8.609044   
2025-06-06 16:30:00+00:00  300.065002  47.317368 -67.978245  8.202905   
2025-06-06 17:30:00+00:00  300.290009  47.050375 -60.642917  7.800553   
2025-06-06 18:30:00+00:00  297.989899  46.978857 -59.967111  7.631942   
2025-06-06 19:30:00+00:00  295.125000  47.136630 -67.531000  7.454660   

                                    OBV Signal  
Datetime                                        
2025-06-06 15:30:00+00:00  2.136260e+09   Hold  
2025-06-06 16:30:00+00:00  2.126695e+09   Hold  
2025-06-06 17:30:00+00:00  2.135303e+09   Hold  
2025-06-06 18:30:00+00:00  2.121891e+09   Hold  
2025-06-06 19:30:00+00:00  2.106101e+09   Hold  
Total Trades: 53
Total Profit/Loss: 116.59
In [5]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [6]:
import yfinance as yf
import talib
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import plotly.graph_objects as go

# Download data

data = df

# ==== Indicators ====
data['RSI'] = talib.RSI(data['Close'], timeperiod=14)
data['ADX'] = talib.ADX(data['High'], data['Low'], data['Close'], timeperiod=14)
data['CCI'] = talib.CCI(data['High'], data['Low'], data['Close'], timeperiod=20)
data['ATR'] = talib.ATR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['OBV'] = talib.OBV(data['Close'], data['Volume'])
data['MACD'], data['MACD_signal'], _ = talib.MACD(data['Close'])

# Drop NA values
data.dropna(inplace=True)

# ==== Labeling for AI ====
future_period = 3
data['Future_Close'] = data['Close'].shift(-future_period)
data['Signal'] = np.where(data['Future_Close'] > data['Close'], 1, 0)  # 1 = Buy, 0 = Sell

# ==== Feature Set ====
features = ['RSI', 'ADX', 'CCI', 'ATR', 'OBV', 'MACD']
X = data[features]
y = data['Signal']

# ==== Train/Test Split ====
split = int(len(data) * 0.8)
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

# ==== Random Forest Model ====
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
data['AI_Signal'] = model.predict(X)

# ==== Backtest ====
position = None
entry_price = 0
returns = []
trade_dates = []
win = 0

for i in range(len(data) - 1):
    signal = data['AI_Signal'].iloc[i]
    price_today = data['Close'].iloc[i]
    price_next = data['Close'].iloc[i + 1]

    if signal == 1 and position != 'Buy':
        entry_price = price_today
        position = 'Buy'
        trade_dates.append(data.index[i])
    elif signal == 0 and position == 'Buy':
        profit = price_today - entry_price
        returns.append(profit)
        if profit > 0:
            win += 1
        position = None

# ==== Backtest Results ====
total_return = sum(returns)
num_trades = len(returns)
win_rate = (win / num_trades) * 100 if num_trades > 0 else 0
mean_return = np.mean(returns)
std_return = np.std(returns)
sharpe_ratio = (mean_return / std_return) * np.sqrt(252) if std_return != 0 else 0

print(f"\n🔍 Backtest Summary:")
print(f"Total Trades: {num_trades}")
print(f"Total Return: ${total_return:.2f}")
print(f"Win Rate: {win_rate:.2f}%")
print(f"Sharpe Ratio: {sharpe_ratio:.2f}")

# ==== Plot AI Signals ====
fig = go.Figure()
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))

fig.add_trace(go.Scatter(
    x=data.index[data['AI_Signal'] == 1],
    y=data['Close'][data['AI_Signal'] == 1],
    mode='markers',
    name='AI Buy',
    marker=dict(color='lime', symbol='triangle-up', size=10)
))
fig.add_trace(go.Scatter(
    x=data.index[data['AI_Signal'] == 0],
    y=data['Close'][data['AI_Signal'] == 0],
    mode='markers',
    name='AI Sell',
    marker=dict(color='red', symbol='triangle-down', size=10)
))

fig.update_layout(
    title='AI Based Buy/Sell Signal for AAPL',
    template='plotly_dark',
    hovermode='x unified',
    xaxis_title='Date',
    yaxis_title='Price',
    height=700
)

fig.show()
🔍 Backtest Summary:
Total Trades: 615
Total Return: $2419.97
Win Rate: 86.83%
Sharpe Ratio: 9.27
In [7]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [12]:
!pip install xgboost
Collecting xgboost
  Obtaining dependency information for xgboost from https://files.pythonhosted.org/packages/29/22/e3ff2dfafe862a91733dfa0aecdb4794aa1d9a18e09a14e118bde0cbc2db/xgboost-3.0.2-py3-none-win_amd64.whl.metadata
  Using cached xgboost-3.0.2-py3-none-win_amd64.whl.metadata (2.1 kB)
Requirement already satisfied: numpy in e:\installedsoftware\anaconda_2\lib\site-packages (from xgboost) (1.26.4)
Requirement already satisfied: scipy in e:\installedsoftware\anaconda_2\lib\site-packages (from xgboost) (1.11.1)
Using cached xgboost-3.0.2-py3-none-win_amd64.whl (150.0 MB)
Installing collected packages: xgboost
ERROR: Could not install packages due to an OSError: [Errno 28] No space left on device

In [13]:
import yfinance as yf
import talib
import pandas as pd
import numpy as np
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import plotly.graph_objects as go

# Step 1: Load Data
df = df

# Step 2: Indicators
df['SMA_20'] = talib.SMA(df['Close'], timeperiod=20)
df['EMA_20'] = talib.EMA(df['Close'], timeperiod=20)
df['RSI'] = talib.RSI(df['Close'], timeperiod=14)
df['MACD'], _, _ = talib.MACD(df['Close'])
df['Upper'], df['Middle'], df['Lower'] = talib.BBANDS(df['Close'])

# Step 3: Create Target (Buy = 1, Sell = 0)
df['Future_Close'] = df['Close'].shift(-1)
df['Signal'] = np.where(df['Future_Close'] > df['Close'], 1, 0)

# Step 4: Clean and Prepare
df.dropna(inplace=True)
features = ['SMA_20', 'EMA_20', 'RSI', 'MACD', 'Upper', 'Lower']
X = df[features]
y = df['Signal']

# Step 5: Train-Test Split
X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle=False, test_size=0.2)

# Step 6: Train XGBoost
model = XGBClassifier(use_label_encoder=False, eval_metric='logloss')
model.fit(X_train, y_train)

# Step 7: Predict Signals
df['Predicted_Signal'] = model.predict(X)

# Step 8: Backtest Module
df['Strategy_Return'] = df['Predicted_Signal'].shift(1) * df['Close'].pct_change()
df['Market_Return'] = df['Close'].pct_change()
df['Cumulative_Strategy'] = (1 + df['Strategy_Return']).cumprod()
df['Cumulative_Market'] = (1 + df['Market_Return']).cumprod()

# Step 9: Plot
fig = go.Figure()
fig.add_trace(go.Scatter(x=df.index, y=df['Cumulative_Strategy'], name='AI Strategy Return'))
fig.add_trace(go.Scatter(x=df.index, y=df['Cumulative_Market'], name='Market Return'))
fig.update_layout(title='Hybrid AI Trading System with XGBoost', template='plotly_dark')
fig.show()

# Optional: Print evaluation
print(classification_report(y_test, model.predict(X_test)))
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[13], line 5
      3 import pandas as pd
      4 import numpy as np
----> 5 from xgboost import XGBClassifier
      6 from sklearn.model_selection import train_test_split
      7 from sklearn.metrics import classification_report

ImportError: cannot import name 'XGBClassifier' from 'xgboost' (E:\installedSoftware\anaconda_2\Lib\site-packages\xgboost\__init__.py)
In [14]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [15]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

data = df

# ইন্ডিকেটর গণনা
data['ADX'] = talib.ADX(data['High'], data['Low'], data['Close'], timeperiod=14)
data['CCI'] = talib.CCI(data['High'], data['Low'], data['Close'], timeperiod=20)
data['OBV'] = talib.OBV(data['Close'], data['Volume'])
data['SAR'] = talib.SAR(data['High'], data['Low'], acceleration=0.02, maximum=0.2)

# Print preview
print(data[['Close', 'ADX', 'CCI', 'OBV', 'SAR']].tail())

# Visualization
fig = go.Figure()

fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
fig.add_trace(go.Scatter(x=data.index, y=data['ADX'], mode='lines', name='ADX'))
fig.add_trace(go.Scatter(x=data.index, y=data['CCI'], mode='lines', name='CCI'))
fig.add_trace(go.Scatter(x=data.index, y=data['OBV'], mode='lines', name='OBV'))
fig.add_trace(go.Scatter(x=data.index, y=data['SAR'], mode='markers', name='SAR', marker=dict(size=4, color='yellow')))

fig.update_layout(
    title='Hybrid Indicator System (ADX, CCI, OBV, SAR)',
    xaxis_title='Date',
    yaxis_title='Value',
    template='plotly_dark',
    hovermode='x unified'
)

fig.show()
                                Close        ADX        CCI           OBV  \
Datetime                                                                    
2025-06-06 15:30:00+00:00  300.454987  47.604899 -74.149204  2.136260e+09   
2025-06-06 16:30:00+00:00  300.065002  47.317368 -67.978245  2.126695e+09   
2025-06-06 17:30:00+00:00  300.290009  47.050375 -60.642917  2.135303e+09   
2025-06-06 18:30:00+00:00  297.989899  46.978857 -59.967111  2.121891e+09   
2025-06-06 19:30:00+00:00  295.125000  47.136630 -67.531000  2.106101e+09   

                                  SAR  
Datetime                               
2025-06-06 15:30:00+00:00  312.247663  
2025-06-06 16:30:00+00:00  307.563143  
2025-06-06 17:30:00+00:00  303.440764  
2025-06-06 18:30:00+00:00  302.049988  
2025-06-06 19:30:00+00:00  302.000000  
In [16]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [17]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

# ডেটা ডাউনলোড (উদাহরণ TSLA)
data = df

# ইন্ডিকেটর গণনা
data['UpperBB'], data['MiddleBB'], data['LowerBB'] = talib.BBANDS(data['Close'], timeperiod=20)
data['SlowK'], data['SlowD'] = talib.STOCH(data['High'], data['Low'], data['Close'])
data['WILLR'] = talib.WILLR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['ULTOSC'] = talib.ULTOSC(data['High'], data['Low'], data['Close'], timeperiod1=7, timeperiod2=14, timeperiod3=28)

# প্রিভিউ
print(data[['Close', 'UpperBB', 'MiddleBB', 'LowerBB', 'SlowK', 'SlowD', 'WILLR', 'ULTOSC']].tail())

# Visualization
fig = go.Figure()

fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))
fig.add_trace(go.Scatter(x=data.index, y=data['UpperBB'], mode='lines', name='Upper BB'))
fig.add_trace(go.Scatter(x=data.index, y=data['MiddleBB'], mode='lines', name='Middle BB'))
fig.add_trace(go.Scatter(x=data.index, y=data['LowerBB'], mode='lines', name='Lower BB'))
fig.add_trace(go.Scatter(x=data.index, y=data['SlowK'], mode='lines', name='Stochastic %K'))
fig.add_trace(go.Scatter(x=data.index, y=data['SlowD'], mode='lines', name='Stochastic %D'))
fig.add_trace(go.Scatter(x=data.index, y=data['WILLR'], mode='lines', name='Williams %R'))
fig.add_trace(go.Scatter(x=data.index, y=data['ULTOSC'], mode='lines', name='Ultimate Oscillator'))

fig.update_layout(
    title='TSLA with Bollinger Bands, Stochastic, Williams %R, Ultimate Oscillator',
    xaxis_title='Date',
    yaxis_title='Indicator Values',
    template='plotly_dark',
    hovermode='x unified'
)

fig.show()
                                Close     UpperBB    MiddleBB     LowerBB  \
Datetime                                                                    
2025-06-06 15:30:00+00:00  300.454987  359.851519  319.331622  278.811726   
2025-06-06 16:30:00+00:00  300.065002  356.126345  316.957092  277.787840   
2025-06-06 17:30:00+00:00  300.290009  351.503672  314.541592  277.579513   
2025-06-06 18:30:00+00:00  297.989899  347.149537  312.217587  277.285638   
2025-06-06 19:30:00+00:00  295.125000  344.788472  310.363788  275.939104   

                               SlowK      SlowD      WILLR     ULTOSC  
Datetime                                                               
2025-06-06 15:30:00+00:00  75.642973  54.134876 -56.345147  37.656924  
2025-06-06 16:30:00+00:00  83.429764  71.435675 -56.970022  40.236609  
2025-06-06 17:30:00+00:00  75.191940  78.088226 -56.385861  42.690558  
2025-06-06 18:30:00+00:00  56.558371  71.726692 -59.935481  45.007534  
2025-06-06 19:30:00+00:00  37.749532  56.499948 -57.313889  44.530196  
In [18]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [19]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

# ডেটা ডাউনলোড (উদাহরণ: MSFT)
data = df

# ইন্ডিকেটর গণনা
data['ADX'] = talib.ADX(data['High'], data['Low'], data['Close'], timeperiod=14)
data['CCI'] = talib.CCI(data['High'], data['Low'], data['Close'], timeperiod=14)
data['MFI'] = talib.MFI(data['High'], data['Low'], data['Close'], data['Volume'], timeperiod=14)
data['OBV'] = talib.OBV(data['Close'], data['Volume'])

# প্রিভিউ
print(data[['Close', 'ADX', 'CCI', 'MFI', 'OBV']].tail())

# Visualization
fig = go.Figure()

fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
fig.add_trace(go.Scatter(x=data.index, y=data['ADX'], mode='lines', name='ADX'))
fig.add_trace(go.Scatter(x=data.index, y=data['CCI'], mode='lines', name='CCI'))
fig.add_trace(go.Scatter(x=data.index, y=data['MFI'], mode='lines', name='MFI'))
fig.add_trace(go.Scatter(x=data.index, y=data['OBV'], mode='lines', name='OBV'))

fig.update_layout(
    title='MSFT: ADX, CCI, MFI, OBV Indicators',
    xaxis_title='Date',
    yaxis_title='Indicator Values',
    template='plotly_dark',
    hovermode='x unified'
)

fig.show()
                                Close        ADX        CCI        MFI  \
Datetime                                                                 
2025-06-06 15:30:00+00:00  300.454987  47.604899 -46.604671  46.581750   
2025-06-06 16:30:00+00:00  300.065002  47.317368 -40.871614  44.639728   
2025-06-06 17:30:00+00:00  300.290009  47.050375 -34.161357  42.308688   
2025-06-06 18:30:00+00:00  297.989899  46.978857 -35.326129  39.745506   
2025-06-06 19:30:00+00:00  295.125000  47.136630 -52.867376  38.984482   

                                    OBV  
Datetime                                 
2025-06-06 15:30:00+00:00  2.136260e+09  
2025-06-06 16:30:00+00:00  2.126695e+09  
2025-06-06 17:30:00+00:00  2.135303e+09  
2025-06-06 18:30:00+00:00  2.121891e+09  
2025-06-06 19:30:00+00:00  2.106101e+09  
In [20]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [21]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

# ডেটা ডাউনলোড (উদাহরণ: TSLA)
data = df

# ইন্ডিকেটর গণনা
data['ATR'] = talib.ATR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['STOCH_K'], data['STOCH_D'] = talib.STOCH(data['High'], data['Low'], data['Close'])
data['WILLR'] = talib.WILLR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['TRIX'] = talib.TRIX(data['Close'], timeperiod=15)

# প্রিভিউ
print(data[['Close', 'ATR', 'STOCH_K', 'STOCH_D', 'WILLR', 'TRIX']].tail())

# Visualization
fig = go.Figure()

fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
fig.add_trace(go.Scatter(x=data.index, y=data['ATR'], mode='lines', name='ATR'))
fig.add_trace(go.Scatter(x=data.index, y=data['STOCH_K'], mode='lines', name='Stochastic %K'))
fig.add_trace(go.Scatter(x=data.index, y=data['STOCH_D'], mode='lines', name='Stochastic %D'))
fig.add_trace(go.Scatter(x=data.index, y=data['WILLR'], mode='lines', name='Williams %R'))
fig.add_trace(go.Scatter(x=data.index, y=data['TRIX'], mode='lines', name='TRIX'))

fig.update_layout(
    title='TSLA: ATR, Stochastic, Williams %R, TRIX Indicators',
    xaxis_title='Date',
    yaxis_title='Indicator Values',
    template='plotly_dark',
    hovermode='x unified'
)

fig.show()
                                Close       ATR    STOCH_K    STOCH_D  \
Datetime                                                                
2025-06-06 15:30:00+00:00  300.454987  8.609044  75.642973  54.134876   
2025-06-06 16:30:00+00:00  300.065002  8.202905  83.429764  71.435675   
2025-06-06 17:30:00+00:00  300.290009  7.800553  75.191940  78.088226   
2025-06-06 18:30:00+00:00  297.989899  7.631942  56.558371  71.726692   
2025-06-06 19:30:00+00:00  295.125000  7.454660  37.749532  56.499948   

                               WILLR      TRIX  
Datetime                                        
2025-06-06 15:30:00+00:00 -56.345147 -0.494906  
2025-06-06 16:30:00+00:00 -56.970022 -0.513636  
2025-06-06 17:30:00+00:00 -56.385861 -0.525459  
2025-06-06 18:30:00+00:00 -59.935481 -0.532537  
2025-06-06 19:30:00+00:00 -57.313889 -0.536856  
In [22]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [23]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go

# ডেটা লোড (উদাহরণ: MSFT)
data = df

# ইন্ডিকেটর গণনা
data['CCI'] = talib.CCI(data['High'], data['Low'], data['Close'], timeperiod=14)
data['MFI'] = talib.MFI(data['High'], data['Low'], data['Close'], data['Volume'], timeperiod=14)
data['ADX'] = talib.ADX(data['High'], data['Low'], data['Close'], timeperiod=14)
data['ULTOSC'] = talib.ULTOSC(data['High'], data['Low'], data['Close'], timeperiod1=7, timeperiod2=14, timeperiod3=28)

# প্রিভিউ
print(data[['Close', 'CCI', 'MFI', 'ADX', 'ULTOSC']].tail())

# Visualization
fig = go.Figure()

fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
fig.add_trace(go.Scatter(x=data.index, y=data['CCI'], mode='lines', name='CCI'))
fig.add_trace(go.Scatter(x=data.index, y=data['MFI'], mode='lines', name='MFI'))
fig.add_trace(go.Scatter(x=data.index, y=data['ADX'], mode='lines', name='ADX'))
fig.add_trace(go.Scatter(x=data.index, y=data['ULTOSC'], mode='lines', name='Ultimate Oscillator'))

fig.update_layout(
    title='MSFT: CCI, MFI, ADX, Ultimate Oscillator',
    xaxis_title='Date',
    yaxis_title='Indicator Values',
    template='plotly_dark',
    hovermode='x unified'
)

fig.show()
                                Close        CCI        MFI        ADX  \
Datetime                                                                 
2025-06-06 15:30:00+00:00  300.454987 -46.604671  46.581750  47.604899   
2025-06-06 16:30:00+00:00  300.065002 -40.871614  44.639728  47.317368   
2025-06-06 17:30:00+00:00  300.290009 -34.161357  42.308688  47.050375   
2025-06-06 18:30:00+00:00  297.989899 -35.326129  39.745506  46.978857   
2025-06-06 19:30:00+00:00  295.125000 -52.867376  38.984482  47.136630   

                              ULTOSC  
Datetime                              
2025-06-06 15:30:00+00:00  37.656924  
2025-06-06 16:30:00+00:00  40.236609  
2025-06-06 17:30:00+00:00  42.690558  
2025-06-06 18:30:00+00:00  45.007534  
2025-06-06 19:30:00+00:00  44.530196  
In [24]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [25]:
import yfinance as yf
import talib
import pandas as pd
import plotly.graph_objects as go
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# Data Load
data = df

# Indicators
data['UpperBB'], data['MiddleBB'], data['LowerBB'] = talib.BBANDS(data['Close'], timeperiod=20)
data['SlowK'], data['SlowD'] = talib.STOCH(data['High'], data['Low'], data['Close'])
data['ATR'] = talib.ATR(data['High'], data['Low'], data['Close'], timeperiod=14)
data['OBV'] = talib.OBV(data['Close'], data['Volume'])
data['RSI'] = talib.RSI(data['Close'], timeperiod=14)

# Drop NaNs
data.dropna(inplace=True)

# Label Creation (RSI-based simple logic)
data['Signal'] = 0  # Default Sell
data.loc[data['RSI'] < 30, 'Signal'] = 1  # Buy when oversold

# Features & Target
features = data[['Close', 'RSI', 'ATR', 'SlowK', 'OBV']]
target = data['Signal']

# Train/Test Split
X_train, X_test, y_train, y_test = train_test_split(features, target, shuffle=False, test_size=0.2)

# AI Model
model = DecisionTreeClassifier(max_depth=3, random_state=42)
model.fit(X_train, y_train)

# Predict
data['AI_Signal'] = model.predict(features)

# Show Report
print("🔍 Classification Report:\n", classification_report(target, data['AI_Signal']))

# Plotting
fig = go.Figure()
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))

# Buy Signal
buy_signal = data[data['AI_Signal'] == 1]
fig.add_trace(go.Scatter(
    x=buy_signal.index,
    y=buy_signal['Close'],
    mode='markers',
    name='🔼 Buy (AI)',
    marker=dict(color='green', size=8, symbol='triangle-up')
))

# Sell Signal
sell_signal = data[data['AI_Signal'] == 0]
fig.add_trace(go.Scatter(
    x=sell_signal.index,
    y=sell_signal['Close'],
    mode='markers',
    name='🔽 Sell (AI)',
    marker=dict(color='red', size=8, symbol='triangle-down')
))

fig.update_layout(
    title='MSFT + AI Signal System (RSI, ATR, OBV, etc)',
    xaxis_title='Date',
    yaxis_title='Price',
    template='plotly_dark',
    hovermode='x unified'
)

fig.show()
🔍 Classification Report:
               precision    recall  f1-score   support

           0       1.00      1.00      1.00      4631
           1       1.00      1.00      1.00       436

    accuracy                           1.00      5067
   macro avg       1.00      1.00      1.00      5067
weighted avg       1.00      1.00      1.00      5067

In [26]:
import pandas as pd

# Load and clean the dataset
file_path = 'tesla_1h.csv'

# Skip first two metadata rows
df = pd.read_csv(file_path, skiprows=2)

# Rename the first column to Datetime
df.rename(columns={"Price": "Datetime"}, inplace=True)

# Convert to datetime and set as index
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime', inplace=True)

# Rename remaining columns
df.columns = ['Close', 'High', 'Low', 'Open', 'Volume']

# Convert all to numeric
df = df.apply(pd.to_numeric, errors='coerce')

# Drop missing rows
df.dropna(inplace=True)

# Preview cleaned DataFrame
print(df.head())
                                Close        High         Low        Open  \
Datetime                                                                    
2022-07-12 13:30:00+00:00  230.348495  239.773331  228.368332  236.846664   
2022-07-12 14:30:00+00:00  235.159988  235.943298  228.883362  230.352371   
2022-07-12 15:30:00+00:00  234.066696  235.593338  232.359634  235.203323   
2022-07-12 16:30:00+00:00  233.326660  234.913330  232.516663  234.012527   
2022-07-12 17:30:00+00:00  234.218338  234.750000  232.900009  233.326660   

                             Volume  
Datetime                             
2022-07-12 13:30:00+00:00  10409515  
2022-07-12 14:30:00+00:00   5272402  
2022-07-12 15:30:00+00:00   3263104  
2022-07-12 16:30:00+00:00   2357956  
2022-07-12 17:30:00+00:00   2123102  
In [32]:
import gym
from gym import spaces
import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt

from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv

# Download data
df = df
df = df[['Open', 'High', 'Low', 'Close', 'Volume']]
df['Returns'] = df['Close'].pct_change()
df.dropna(inplace=True)

# Custom Trading Environment
class TradingEnv(gym.Env):
    def __init__(self, df):
        super(TradingEnv, self).__init__()
        self.df = df.reset_index()
        self.max_steps = len(df) - 1
        self.current_step = 0
        self.initial_balance = 10000
        self.balance = self.initial_balance
        self.shares_held = 0
        self.net_worth = self.initial_balance

        # Actions: 0 = Hold, 1 = Buy, 2 = Sell
        self.action_space = spaces.Discrete(3)

        # Observation: [Open, High, Low, Close, Volume, Shares Held, Balance]
        self.observation_space = spaces.Box(
            low=0, high=np.inf, shape=(7,), dtype=np.float32
        )

    def _get_obs(self):
        obs = np.array([
            self.df.loc[self.current_step, 'Open'],
            self.df.loc[self.current_step, 'High'],
            self.df.loc[self.current_step, 'Low'],
            self.df.loc[self.current_step, 'Close'],
            self.df.loc[self.current_step, 'Volume'],
            self.shares_held,
            self.balance
        ], dtype=np.float32)
        return obs

    def step(self, action):
        current_price = self.df.loc[self.current_step, 'Close']
        done = False
        reward = 0

        # Action 1: Buy
        if action == 1 and self.balance >= current_price:
            shares_bought = self.balance // current_price
            cost = shares_bought * current_price
            self.balance -= cost
            self.shares_held += shares_bought

        # Action 2: Sell
        elif action == 2 and self.shares_held > 0:
            revenue = self.shares_held * current_price
            self.balance += revenue
            self.shares_held = 0

        self.current_step += 1

        self.net_worth = self.balance + self.shares_held * current_price
        reward = self.net_worth - self.initial_balance

        if self.current_step >= self.max_steps:
            done = True

        info = {'net_worth': self.net_worth}

        return self._get_obs(), reward, done, info

    def reset(self):
        self.balance = self.initial_balance
        self.shares_held = 0
        self.net_worth = self.initial_balance
        self.current_step = 0
        return self._get_obs()

    def render(self, mode='human'):
        print(f'Step: {self.current_step}')
        print(f'Balance: {self.balance}')
        print(f'Shares held: {self.shares_held}')
        print(f'Net worth: {self.net_worth}')

# Create environment
env = TradingEnv(df)
env = DummyVecEnv([lambda: env])

# Train PPO agent
model = PPO("MlpPolicy", env, verbose=1)
model.learn(total_timesteps=20000)

# Test agent
obs = env.reset()
done = False
actions = []
prices = df['Close'].values
while not done:
    action, _states = model.predict(obs)
    obs, reward, done, info = env.step(action)
    actions.append(action[0])

# Visualize results with Buy/Sell markers
plt.figure(figsize=(15, 7))
plt.plot(df.index, df['Close'], label='Close Price')

buy_signals = [i for i, a in enumerate(actions) if a == 1]
sell_signals = [i for i, a in enumerate(actions) if a == 2]

plt.scatter(df.index[buy_signals], df['Close'].iloc[buy_signals], marker='^', color='g', label='Buy Signal', s=100)
plt.scatter(df.index[sell_signals], df['Close'].iloc[sell_signals], marker='v', color='r', label='Sell Signal', s=100)

plt.title('AAPL Close Price and RL Trading Signals')
plt.legend()
plt.show()
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[32], line 1
----> 1 import gym
      2 from gym import spaces
      3 import numpy as np

ModuleNotFoundError: No module named 'gym'
In [ ]: